package com.tanhua.dubbo.server.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.tanhua.common.pojo.*;
import com.tanhua.common.utils.UserThreadLocal;
import com.tanhua.dubbo.server.pojo.Dimensions;
import com.tanhua.dubbo.server.pojo.SimilarYou;
import com.tanhua.dubbo.server.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 *
 * @ClassName: TestSoulService
 * @Author:王晨晗
 * @Description: 灵魂测试业务层
 * @Date: 2022/01/10/14:20
 */
@Service
@Slf4j
public class TestSoulService {
    @Autowired
    private UserReportService userReportService;
    @Autowired
    private QuestionnaireService questionnaireService;
    @Autowired
    private SoulQuestionService soulQuestionService;
    @Autowired
    private SoulOptionService soulOptionService;
    @Autowired
    private UserLockService userLockService;
    @Autowired
    private QuestionnaireResultService questionnaireResultService;
    @Autowired
    private UserInfoService userInfoService;

    /**
     * @description 灵魂测试问卷列表
     * @return
     */
    public List<QuestionnaireVo> queryQuestionnaireList() {
        //获取当前用户信息
        User user = UserThreadLocal.get();
        //查询所有的问卷列表
        List<Questionnaire> questinnaireList = questionnaireService.findAll();
        //创建问卷封装对象集合 , 获取到封装的问卷对象
        List<QuestionnaireVo> questionnaireListVo = fillQuestionnaireVo(questinnaireList);
        //返回问卷封装集合
        return questionnaireListVo;
    }

    /**
     * @description 保存测试结果
     * @param answers
     * @return
     */
    public String saveAnswer(List<AnswersVo> answers) {
        Integer score = 0;          //统计用户得分
        Long questionId = 0L;       //问卷题目id
        //用户报告对象
        UserReport userReport = new UserReport();

        //计算用户的分数 遍历用户回答结果集
        for (AnswersVo answersVo : answers) {
            questionId = answersVo.getQuestionId();     //问题id
            Long optionId = answersVo.getOptionId();    //选项id
            //根据选项id 获取到选项对象;
            SoulOption option = soulOptionService.getOption(optionId);
            //计算得分信息和维度得分;
            userReport.setExtroversion(userReport.getExtroversion() + option.getExtroversion());    //维度
            userReport.setRationality(userReport.getRationality() + option.getRationality());   //理性
            userReport.setJudgement(userReport.getJudgement() + option.getJudgement()); //判断
            userReport.setAbstraction(userReport.getAbstraction() + option.getAbstraction());  //抽象

            score += option.getScore();     //总得分
        }

        //通过题目id查到对应的问卷id
        Long questionnaireId = soulQuestionService.getQuestionnaireId(questionId);
        //开启下一级问卷的访问权限
        if (questionnaireId<=2){
            //执行开启问卷权限
            userLockService.openUserLock(questionnaireId + 1);
        }

        //根据问卷id,查看结果表，看总分在哪个区间，判断你的性格，并把数据都添加到报告表里
        List<QuestionnaireResult> questionnaireResults = questionnaireResultService.getQuestionnaireResultList(questionnaireId);
        //为用户报告对象填充对象;
        //UserReport userReport = new UserReport();
        userReport.setUserId(UserThreadLocal.get().getId());        //用户id
        userReport.setQuestionnaireId(questionnaireId);             //问卷id
        //遍历问卷结果集
        for (QuestionnaireResult questionnaireResult : questionnaireResults) {
            //获取记过中的分值区间
            String[] split = questionnaireResult.getScope().split(",");
            //判断用户答题的得分,是否在该结果区间类;
            if (score >= Integer.valueOf(split[0]) && score <= Integer.valueOf(split[1])) {
                //分值在区间内 ,封装用户报告数据
                userReport.setResultId(questionnaireResult.getId());                //问卷结果id;
                userReport.setCover(questionnaireResult.getCover());                //封面
                //结束循环
                break;
            }
        }

        //保存报告
        boolean result = userReportService.save(userReport);
        //判断保存结果是否成功
        if (!result){
            //保存失败,返回空值
            return null;
        }
        //保存成功 , 返回报告id
        return userReport.getId().toString();
    }

    /**
     * @description 根据报告id获取用户报告
     * @param reportId
     * @return
     */
    public TestResultVo getUserReport(Long reportId) {
        //根据报告id 获取报告信息
        UserReport userReport = userReportService.findByReportId(reportId);
        //创建响应对象
        TestResultVo testResultVo = new TestResultVo();
        //根据报告中的测试结果id,获取结果对象
        QuestionnaireResult questionnaireResult = questionnaireResultService.getQuestionnaireResult(userReport.getResultId());
        //封装信息
        testResultVo.setConclusion(questionnaireResult.getContent());       //报告描述
        testResultVo.setCover(userReport.getCover());                       //封面
        //创建集合,保存维度信息
        List<Dimensions> dimensionsList = new ArrayList<>();
        //封装维度信息
        dimensionsList.add(new Dimensions("抽象" , userReport.getAbstraction() + "%"));    //抽象
        dimensionsList.add(new Dimensions("外向" , userReport.getExtroversion() + "%"));    //外向
        dimensionsList.add(new Dimensions("判断" , userReport.getJudgement() + "%"));    //判断
        dimensionsList.add(new Dimensions("理性" , userReport.getRationality() + "%"));    //理性
        //封装相似的人
        //根据结果id获取报告表中一样的用户
        List<Object> userIds = userReportService.getUserIdByResultId(userReport.getResultId() , UserThreadLocal.get().getId());
        //判断id集合是否为空;
        if (CollUtil.isNotEmpty(userIds)){
            //根据用户id列表,查询用户详细信息
            List<UserInfo> userInfoList = userInfoService.queryUserInfoByList(userIds);
            //创建相似的人集合
            List<SimilarYou> similarYouList = new ArrayList<>();
            //遍历用户详细信息集合,封装数据
            for (UserInfo userInfo : userInfoList) {
                //添加信息到集合中
                similarYouList.add(new SimilarYou(userInfo.getUserId() , userInfo.getLogo()));
            }
            testResultVo.setSimilarYou(similarYouList);     //相似的人
        }
        //将维度集合和相似的人集合,添加的响应对象中
        testResultVo.setDimensions(dimensionsList);     //维度数据

        //返回响应结果
        return testResultVo;
    }


    /**
     * @description 封装问卷列表信息
     * @param questinnaireList  问卷列表
     * @return
     */
    public List<QuestionnaireVo> fillQuestionnaireVo(List<Questionnaire> questinnaireList) {
        //获取用户信息
        User user = UserThreadLocal.get();
        //创建问卷封装对象集合
        List<QuestionnaireVo> questionnaireListVo = new ArrayList<>();
        //判断问卷是否为空
        if (!CollectionUtils.isEmpty(questinnaireList)) {
            //遍历得到的问卷列表
            for (Questionnaire questinnaire : questinnaireList) {
                //获取该问卷对应的所有问题
                List<SoulQuestion> soulQuestionList = soulQuestionService.findById(questinnaire.getId());
                //封装试题vo对象集合
                List<Questionsvo> questionsVos = fillSoulQuestion(soulQuestionList);
                //创建问卷vo封装对象
                QuestionnaireVo questionnaireVo = new QuestionnaireVo();
                BeanUtils.copyProperties(questinnaire, questionnaireVo);            //将查询的问卷信息中与问卷vo相同的属性,进行映射赋值,
                questionnaireVo.setId(String.valueOf(questinnaire.getId()));        //问卷id
                questionnaireVo.setStar(Convert.toInt(questinnaire.getStar()));     //问卷星级
                questionnaireVo.setQuestions(questionsVos);                         //试题Vo集合

                //判断问卷是否已解锁 ,根据用户id和问卷id查询用户锁表,判断该问卷的锁状态 , 设置用户的锁状态
                questionnaireVo.setIsLock(userLockService.getUserLock(user.getId(), questinnaire.getId()));
                //查询用户最新报告;
                UserReport userReport = userReportService.getUserReportByUserId(user.getId() , questinnaire.getId());
                //判断用户报告是否存在 存在保存最新报告的id
                if (ObjectUtil.isNotEmpty(userReport)){
                    //封装用户最新报告id;
                    questionnaireVo.setReportId(String.valueOf(userReport.getId()));
                }
                //添加到问卷Vo集合中
                questionnaireListVo.add(questionnaireVo);
            }
            //返回封装完成的问卷Vo集合
            return questionnaireListVo;
        }
        //问卷为空 返回空集合
        return ListUtil.empty();
    }

    /**
     * @description 封装问卷对应的问题集合
     * @param soulQuestionList
     * @return
     */
    public List<Questionsvo> fillSoulQuestion(List<SoulQuestion> soulQuestionList){
        //创建试题 vo封装对象集合
        List<Questionsvo> questionsVos = new ArrayList<>();
        //如果不为空,封装问题集合
        if (!CollectionUtils.isEmpty(soulQuestionList)) {
            //遍历题目集合 获取每个题目的对应选项内容
            for (SoulQuestion questions : soulQuestionList) {
                //获取题目对应得选项
                List<SoulOption> soulOptionList = soulOptionService.findById(questions.getId());
                //封装选项vo对象集合
                List<OptionsVo> optionsVos = fillOption(soulOptionList);
                //创建试题封装vo对象
                Questionsvo questionsvo = new Questionsvo();
                questionsvo.setId(String.valueOf(questions.getId()));   //试题的id
                questionsvo.setQuestion(questions.getStem());           //试题内容
                questionsvo.setOptions(optionsVos);                     //选项vo集合
                //添加到试题vo封装集合
                questionsVos.add(questionsvo);
            }
            //返回试题Vo集合
            return questionsVos;
        }
        //为空 返回空集合 表示问题集合无;
        return ListUtil.empty();
    }

    /**
     * @description  封装选项的响应集合
     * @param soulOptionList
     * @return
     */
    public List<OptionsVo> fillOption(List<SoulOption> soulOptionList){
        //判断选项集合是否为空
        if (!CollUtil.isEmpty(soulOptionList)){
            //创建 选项vo封装对象集合
            List<OptionsVo> optionsVos = new ArrayList<>();
            //遍历选项集合
            for (SoulOption options : soulOptionList) {
                //创建 选项vo封装对象
                OptionsVo optionsVo = new OptionsVo();
                optionsVo.setId(String.valueOf(options.getId()));    //选项id
                optionsVo.setOption(options.getContent());           //选项内容
                //添加到选项vo集合
                optionsVos.add(optionsVo);
            }
            //返回选项vo集合
            return optionsVos;
        }
        //选项集合为空,返回空集合即可
        return ListUtil.empty();
    }
}
